package com.luo.gmall.item.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.luo.gmall.item.feign.GmallPmsClient;
import com.luo.gmall.item.feign.GmallSmsClient;
import com.luo.gmall.item.feign.GmallWmsClient;
import com.luo.gmall.item.service.ItemService;
import com.luo.gmall.item.vo.ItemVo;
import com.luo.gmall.pms.entity.*;
import com.luo.gmall.pms.vo.ItemGroupVo;
import com.luo.gmall.pms.vo.SaleAttrValueVo;
import com.luo.gmall.sms.vo.ItemSaleVo;
import com.luo.gmall.wms.entity.WareSkuEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * @author Zoro
 * @date 2021年11月18
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private GmallSmsClient gmallSmsClient;

    @Autowired
    private GmallWmsClient gmallWmsClient;

    @Autowired
    private GmallPmsClient gmallPmsClient;

    @Autowired
    private ExecutorService executorService;

    @Autowired
    private TemplateEngine templateEngine;

    @Override
    public ItemVo queryItemBySkuId(Long skuId) {
        ItemVo itemVo = new ItemVo();
        // 1.根据skuId查询sku
        CompletableFuture<SkuEntity> skuEntityFuture = CompletableFuture.supplyAsync(() -> {
            SkuEntity skuEntity = gmallPmsClient.querySkuById(skuId).getData();
            if (skuEntity == null) {
                throw new RuntimeException("当前商品id没有对应的商品！");
            }
            // 设置中间主体部分所需字段
            BeanUtils.copyProperties(skuEntity, itemVo);
            itemVo.setSkuId(skuId);
            return skuEntity;
        }, executorService);

        // 2.根据三级分类的id查询一二三级分类
        CompletableFuture<Void> categoriesFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            List<CategoryEntity> oneTwoThreeCategory = gmallPmsClient.queryLevelOneTwoThreeByLevelThreeId(skuEntity.getCategoryId()).getData();
            // 设置商品详情页面包屑所需字段
            itemVo.setCategories(oneTwoThreeCategory);
        }, executorService);

        // 3.根据品牌id查询品牌
        CompletableFuture<Void> brandEntityFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            BrandEntity brandEntity = gmallPmsClient.queryBrandById(skuEntity.getBrandId()).getData();
            // 设置品牌信息
            if (brandEntity != null) {
                itemVo.setBrandId(brandEntity.getId());
                itemVo.setBrandName(brandEntity.getName());
            }
        }, executorService);

        // 4.根据spuId查询spu
        CompletableFuture<Void> spuEntityFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            SpuEntity spuEntity = gmallPmsClient.querySpuById(skuEntity.getSpuId()).getData();
            // 设置spu信息
            if (spuEntity != null) {
                itemVo.setSpuId(spuEntity.getId());
                itemVo.setSpuName(spuEntity.getName());
            }
        }, executorService);

        // 5.根据skuId查询sku的图片列表
        CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {
            List<SkuImagesEntity> skuImagesEntities = gmallPmsClient.queryListSkuImagesBySkuId(skuId).getData();
            // 设置sku图片列表
            itemVo.setImages(skuImagesEntities);
        }, executorService);

        // 6.根据skuId查询营销信息
        CompletableFuture<Void> salesFuture = CompletableFuture.runAsync(() -> {
            List<ItemSaleVo> itemSaleVos = gmallSmsClient.queryListSalesBySkuId(skuId).getData();
            itemVo.setSales(itemSaleVos);
        }, executorService);

        // 7.根据skuId查询库存信息
        CompletableFuture<Void> storeFuture = CompletableFuture.runAsync(() -> {
            List<WareSkuEntity> wareSkuEntities = gmallWmsClient.queryWareSkuBySkuId(skuId).getData();
            if (CollectionUtils.isEmpty(wareSkuEntities)) {
                boolean isStore = wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0);
                itemVo.setStore(isStore);
            }
        }, executorService);

        // 8.根据spuId查询spu下所有sku的销售属性  saleAttrs
        CompletableFuture<Void> saleAttrsFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            List<SaleAttrValueVo> saleAttrValueVos = gmallPmsClient.querySaleAttrValueVosBySpuId(skuEntity.getSpuId()).getData();
            itemVo.setSaleAttrs(saleAttrValueVos);
        }, executorService);

        // 9.根据skuId查询当前sku的销售属性
        CompletableFuture<Void> saleAttrFuture = CompletableFuture.runAsync(() -> {
            List<SkuAttrValueEntity> skuAttrValueEntities = gmallPmsClient.queryCurrentSaleAttrValuesBySkuId(skuId).getData();
            if (!CollectionUtils.isEmpty(skuAttrValueEntities)) {
                itemVo.setSaleAttr(skuAttrValueEntities.stream().collect(Collectors.toMap(SkuAttrValueEntity::getAttrId, SkuAttrValueEntity::getAttrValue)));
            }
        }, executorService);

        // 10.根据spuId查询spu下所有销售属性组合与skuId的映射关系
        CompletableFuture<Void> skuJsonsFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            String skuJsons = gmallPmsClient.querySpuAllSalesComboMapSkuIdBySpuId(skuEntity.getSpuId()).getData();
            itemVo.setSkuJsons(skuJsons);
        }, executorService);

        // 11.根据spuId查询描述信息
        CompletableFuture<Void> spuImagesFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            SpuDescEntity spuDescEntity = gmallPmsClient.querySpuDescById(skuEntity.getSpuId()).getData();
            if (spuDescEntity != null) {
                String decript = spuDescEntity.getDecript();
                itemVo.setSpuImages(Arrays.asList(decript.split(";")));
            }
        }, executorService);

        // 12.根据cid spuId skuId查询规格参数分组及组下的规格参数和值
        CompletableFuture<Void> groupsFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            List<ItemGroupVo> itemGroupVos = gmallPmsClient.queryWithItemGroupByCategoryIdAndSpuIdAndSkuId(skuEntity.getCategoryId(), skuEntity.getSpuId(), skuId).getData();
            itemVo.setGroups(itemGroupVos);
        }, executorService);

        CompletableFuture.allOf(categoriesFuture, brandEntityFuture, spuEntityFuture, imagesFuture, salesFuture,
                storeFuture, saleAttrsFuture, saleAttrFuture, skuJsonsFuture, spuImagesFuture, groupsFuture).join();
        return itemVo;
    }

    private void createHtml(Long skuId) {
        // 获取itemVo数据
        ItemVo itemVo = queryItemBySkuId(skuId);
        // 上下文对象的初始化
        Context context = new Context();
        // 页面静态化所有需要的数据模型
        context.setVariable("itemVo", itemVo);
        // 初始化文件流，输出静态页面到硬盘的某个目录下，注意需要提前创建该html需要
        try (PrintWriter printWriter = new PrintWriter(new File("E:\\project\\html\\" + skuId + ".html"))) {
            templateEngine.process("item", context, printWriter);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 异步生成静态页面
     */
    @Override
    public void asybcExcute(Long skuId) {
        executorService.execute(() -> createHtml(skuId));
    }

}
